# coding=utf-8
import os
import time, requests, json
from urllib3.exceptions import InsecureRequestWarning
import hmac
import hashlib
import base64
import urllib.parse
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
from email import encoders
from email.header import Header
from config import EMAIL_SERVER

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


class WeixinRobot:
    def __init__(self, key):
        self.key = key  # 修改key即可
        self.url = f'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={self.key}'
        self.headers = {
            'Content-Type': 'application/json'
        }

    def text_api(self, text, name=None):
        try:
            data = json.dumps({
                "msgtype": "text",
                "text": {
                    "content": text,
                    "mentioned_list": [name],
                    # "mentioned_mobile_list":["13848886443","@all"] #手机号列表 非必填
                }
            })
            res = requests.request('POST', url=self.url, headers=self.headers, data=data, verify=False)
            print('文本消息', res.text)
            res.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))

    def img_api(self, file):
        try:
            with open(file, 'rb') as f:
                # 转化base64编码格式
                file_data = f.read()
                encode_str = base64.b64encode(file_data)
                # print(str(encode_str, 'utf-8'))  # 重新编码数据

                # 生成md5
                md = hashlib.md5()
                md.update(file_data)  # 在md上面更新所需要加密的字符串
                md5 = md.hexdigest()  # 获取加密后的字符串
                f.close()
            data = json.dumps({
                "msgtype": "image",
                "image": {
                    "base64": str(encode_str, 'utf-8'),
                    "md5": md5
                }
            })
            res = requests.request("POST", url=self.url, headers=self.headers, data=data, verify=False)
            print('图片消息', res.text)
            res.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))

    def file_api(self, file):
        try:
            file_url = f'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={self.key}&type=file'
            headers_form = {
                'Content-Type': 'multipart/form-data'
            }
            file_data = {
                'file': open(file, 'rb')
            }
            file_response = requests.post(url=file_url, headers=headers_form, files=file_data, verify=False)
            # print(file_response.json())
            media_id = file_response.json()['media_id']
            data = json.dumps({
                "msgtype": "file",
                "file": {
                    "media_id": media_id
                }
            })
            res = requests.post(url=self.url, headers=self.headers, data=data, verify=False)
            print('文件消息', res.text)
            res.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))

    def img_text_api(self, title, link_url, img_url=None, description=None):
        try:
            data = json.dumps({
                "msgtype": "news",
                "news": {
                    "articles": [
                        {
                            "title": title,
                            "description": description,
                            "url": link_url,  # 点击图片后跳转的链接。
                            "picurl": img_url  # 图文消息的图片链接
                        }
                    ]
                }
            }
            )
            res = requests.post(url=self.url, headers=self.headers, data=data, verify=False)
            print('图文消息', res.text)
            res.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))

    def markdown_api(self, text):
        try:
            data = json.dumps({
                "msgtype": "markdown",
                "markdown": {
                    "content": text
                }
            })
            res = requests.post(url=self.url, headers=self.headers, data=data, verify=False)
            print('markdown消息', res.text)
            res.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))


class DingdingRobot:
    def __init__(self, token, secret):
        # 计算签名
        timestamp = str(round(time.time() * 1000))
        secret_enc = secret.encode('utf-8')
        string_to_sign = '{}\n{}'.format(timestamp, secret)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

        self.url = f'https://oapi.dingtalk.com/robot/send?access_token={token}&timestamp={timestamp}&sign={sign}'
        self.headers = {'Content-Type': 'application/json'}

    # 发送文本消息
    def send_text_message(self, text, phone=None):
        try:
            data = {
                "at": {
                    "atMobiles": [
                        phone  # 被艾特人手机号
                    ],
                    "isAtAll": False  # 是否艾特全体成员
                },
                "text": {
                    "content": text
                },
                "msgtype": "text"
            }
            response = requests.post(url=self.url, headers=self.headers, data=json.dumps(data))
            response.raise_for_status()  # 检查HTTP错误
            print('文本消息', response.text)
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="钉钉机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="钉钉机器人报错了", info=str(e))

    # 发送链接消息
    def send_link_message(self, text, title, message_url, pic_url=None):
        try:
            data = {
                "msgtype": "link",
                "link": {
                    "text": text,
                    "title": title,
                    "picUrl": pic_url,
                    "messageUrl": message_url
                }
            }
            response = requests.post(url=self.url, headers=self.headers, data=json.dumps(data))
            response.raise_for_status()  # 检查HTTP错误
            print('链接消息', response.text)
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="钉钉机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="钉钉机器人报错了", info=str(e))

    # Markdown消息
    def markdown(self, title, text, phone=None):
        try:
            data = {
                "msgtype": "markdown",
                "markdown": {
                    "title": title,
                    "text": text
                },
                "at": {
                    "atMobiles": [
                        phone
                    ],
                    "isAtAll": False
                }
            }
            response = requests.post(url=self.url, headers=self.headers, data=json.dumps(data))
            response.raise_for_status() # 检查HTTP错误
            print('Markdown消息', response.text)
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="钉钉机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="钉钉机器人报错了", info=str(e))


    # 独立跳转 ActionCard 类型
    def action_card(self, title, text, actionURL1, actionURL2):
        try:
            data = {
                "msgtype": "actionCard",
                "actionCard": {
                    "title": title,
                    "text": text,
                    "btnOrientation": "0",
                    "btns": [
                        {
                            "title": "测试平台",
                            "actionURL": f"dingtalk://dingtalkclient/page/link?url={actionURL1}&pc_slide=false"
                        },
                        {
                            "title": "测试报告",
                            "actionURL": f"dingtalk://dingtalkclient/page/link?url={actionURL2}&pc_slide=false"
                        }
                    ]
                }
            }
            response = requests.post(url=self.url, headers=self.headers, data=json.dumps(data))
            response.raise_for_status()  # 检查HTTP错误
            print('独立跳转ActionCard消息', response.text)
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="钉钉机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="钉钉机器人报错了", info=str(e))


class FeishuRobot():
    def __init__(self, token, secret):
        # 拼接timestamp和secret
        string_to_sign = '{}\n{}'.format(str(int(time.time())), secret)
        hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()
        # 对结果进行base64处理
        self.sign = base64.b64encode(hmac_code).decode('utf-8')

        self.url = f"https://open.feishu.cn/open-apis/bot/v2/hook/{token}"

    def send_message(self, title, message, url):
        try:
            data = {
                "timestamp": str(int(time.time())),
                "sign": self.sign,
                "msg_type": "post",
                "content": {
                    "post": {
                        "zh_cn": {
                            "title": title,
                            "content": [
                                [{
                                    "tag": "text",
                                    "text": message
                                }, {
                                    "tag": "a",
                                    "text": "测试报告",
                                    "href": url
                                }, {
                                    "tag": "text",
                                    "text": "\n"
                                },
                                    #     {
                                    #     "tag": "at",
                                    #     "user_id": "d97edcf8"
                                    # }
                                ]
                            ]
                        }
                    }
                }
            }
            response = requests.post(url=self.url, json=data)
            print(response.text)
            response.raise_for_status()  # 检查HTTP错误
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err}")
            send_email(subject="企业微信机器人报错了", info=str(http_err))
        except Exception as e:
            print(f"An error occurred: {e}")
            send_email(subject="企业微信机器人报错了", info=str(e))


def send_email(subject, info ,file_paths: list = None):  # file_paths传列表
    sender_name = EMAIL_SERVER['sender_name']  # 发件人名称
    sender_email = EMAIL_SERVER['sender_email']  # 你的发件人邮箱（163邮箱）
    sender_password = EMAIL_SERVER['sender_password']  # 你的发件人邮箱密码
    receiver_email = EMAIL_SERVER['receiver_email'] # 收件人邮箱
    # 邮件主题和HTML格式内容
    # subject = "iChemBio测试报告"
    body = f"<html><body><h1>{info}</h1></body></html>"

    if file_paths is None:
        file_paths = []

    # 设置SMTP服务器和端口号（163邮箱）
    smtp_server = "smtp.163.com"
    smtp_port = 25  # 或使用465端口（SSL加密），但需要将server.starttls()g去掉

    server = None  # 初始化server变量

    try:
        # 登录SMTP服务器
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.login(sender_email, sender_password)

        # 创建一个包含邮件内容的MIMEMultipart对象
        message = MIMEMultipart()
        message["From"] = str(Header(sender_name, "utf-8")) + " <" + sender_email + ">"
        message["To"] = receiver_email
        message["Subject"] = subject

        # 添加HTML内容
        msg = MIMEText(body, "html", "utf-8")
        message.attach(msg)

        # 添加文件附件
        if file_paths:  # 检查file_paths是否非空
            for file_path in file_paths:
                with open(file_path, "rb") as f:
                    attachment = MIMEBase("application", "octet-stream")
                    attachment.set_payload(f.read())
                    encoders.encode_base64(attachment)
                    file_name = os.path.basename(file_path)
                    attachment.add_header("Content-Disposition", "attachment",
                                          filename=Header(file_name, "utf-8").encode())
                    message.attach(attachment)

        # 发送邮件
        server.sendmail(sender_email, receiver_email, message.as_string())
        print("邮件发送成功！")
    except Exception as e:
        print(f"邮件发送失败：{e}")
    finally:
        # 关闭连接
        if server is not None:
            server.quit()

# 钉钉调用示例
# DingdingRobot().send_text_message('测试文本消息', phone='13848886443')
# DingdingRobot().send_link_message(
#     text='点击查看测试报告详情',
#     title='测试报告',
#     pic_url='https://tmpic.tmkoo.com/1143db4c23ca7d8c967541ee3bb13223?v=2022',
#     message_url='http://localhost:63342/%E6%95%B0%E6%8D%AE%E7%AB%99/reports/report_api.html'
# )
# DingdingRobot().markdown(
#     '测试报告',
#     "## 测试报告\n"
#     "### [aaron](http://192.168.10.163:88/ui-testreports/aaron_testreport/reports/complete.html)\n"
#     "### [1plus](http://192.168.10.163:88/ui-testreports/1plus_testreport/reports/complete.html)\n"
#     "### [a2bchem](http://192.168.10.163:88/ui-testreports/a2bchem_ui_report.html)\n"
#     "### [aablocks](http://192.168.10.163:88/ui-testreports/aablocks_testreport/reports/complete.html)\n"
#     "### [aaonpharma](http://192.168.10.163:88/ui-testreports/aaonpharma_report.html)\n"
#     "### [1Scientific](http://192.168.10.163:88/ui-testreports/1st_Scientific_report.html)\n"
# )
# DingdingRobot('ef198c4b32f31fa1b7ac5557df13717c4fb491599fbb3dab4d751fbea3bda1ee','SEC161f2f1cd704327748770bc92999dc84aac781bb5ac2023015529160241cb992').action_card(
#                 f'project_name 运行报错',
#                 f"![screenshot](https://gitee.com/shangguanyi666/picture/raw/master/%E8%BF%90%E8%A1%8C%E5%A4%B1%E8%B4%A5.png) \n\n #### project_name 运行报错 \n\n 请通过测试报告查看详情",
#                 "https://www.shangguangroup.top",
#                 f"path"
#             )

# 企业微信调用示例
# WeixinRobot().img_api(r'C:\Users\shangguanyi\Desktop\上官一\后台\3.png')
# WeixinRobot().file_api(r'E:\PycharmProjects\ichempro\message_api\wechat_dingding_bot_api.py')
# WeixinRobot('81971e4f-d268-4031-9059-2edd14f6a975').img_text_api('Acco 运行报错', 'https://www.shangguangroup.top/','https://gitee.com/shangguanyi666/picture/raw/master/%E8%BF%90%E8%A1%8C%E5%A4%B1%E8%B4%A5.png', '请通过测试报告查看详情')
# WeixinRobot('81971e4f-d268-4031-9059-2edd14f6a975').markdown_api("# 测试报告:\n"
#                            "## [aaron](http://192.168.10.163:88/ui-testreports/aaron_testreport/reports/complete.html)\n"
#                            "## [1plus](http://192.168.10.163:88/ui-testreports/1plus_testreport/reports/complete.html)\n"
#                            "## [a2bchem](http://192.168.10.163:88/ui-testreports/a2bchem_ui_report.html)\n"
#                            "## [aablocks](http://192.168.10.163:88/ui-testreports/aablocks_testreport/reports/complete.html)\n"
#                            "## [aaonpharma](http://192.168.10.163:88/ui-testreports/aaonpharma_report.html)\n"
#                            "## [1Scientific](http://192.168.10.163:88/ui-testreports/1st_Scientific_report.html)\n")

# 飞书调用示例
# FeishuRobot('741a4e07-13e8-4fa2-9b32-bd2d33594912', 'qEU4KjvzAqLlVWbWvbfoyh').send_message('Acco运行报错',
#                                                                                            '请通过测试报告查看详情：',
#                                                                                            'http://192.168.10.163:88/uicases')
